package com.mida.bms.report.service.impl;

import com.mida.bms.report.entity.DocReportCollectImg;
import com.mida.bms.report.service.DocReportCollectImgService;
import com.mida.bms.report.service.ImageService;
import com.mida.bms.report.service.SoidService;
import com.mida.bms.report.util.FTPUtil;
import com.mida.bms.report.vo.ImageVo;
import com.mida.tool.common.result.ActionResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;

import static com.mida.tool.common.result.BaseResult.buildActionSuccess;
import static com.mida.tool.common.result.BaseResult.buildActionWarn;

/**
 * @author bzy
 */
@Service
@Slf4j
@DependsOn("loadFromDatabasePropertyConfig")
public class ImageServiceImpl implements ImageService {

    private static final int ZERO = 0;

    private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class);

    @Value("${ftp.image.host}")
//    @Value("${image.url}")
    private String url;

    @Value("${ftp.image.port}")
//    @Value("${image.port}")
    private Integer port;

    @Value("${wiki.imagePath}")
    private String wikiImagePath;



    @Autowired
    private DocReportCollectImgService docReportCollectImgService;


    /**
     * ID生成器
     */
    @Autowired
    private SoidService soidService;



    /**
     * 采集到的图片上传
     * @param file 文件
     * @return
     * @throws IOException
     */
    @Override
    public String uploadImg(MultipartFile file, String postId, String personSoid, String customerSoid,
                            String registrationSoid, Long loginUserId) throws IOException {
        //1、连接ftp服务器
        FTPClient ftpClient = new FTPClient();
        ftpClient.connect(url, port);
        //2、登录ftp服务器
        ftpClient.login("anonymous", "");
        String imagePath = this.upload(ftpClient, postId, file, personSoid);
        DocReportCollectImg examination = docReportCollectImgService.queryExamination(postId);
        if (null == examination){
            DocReportCollectImg docReportCollectImg = new DocReportCollectImg();
            docReportCollectImg.setReportCollectImgSoid(soidService.getSoid());
            docReportCollectImg.setExamCheckSoid(Long.valueOf(postId));
            docReportCollectImg.setApntPersonSoid(Long.valueOf(personSoid));
            docReportCollectImg.setCustomerSoid(Long.valueOf(customerSoid));
            docReportCollectImg.setImagePath(imagePath);
            docReportCollectImg.setCreateDate(new Date());
            docReportCollectImg.setCreator(loginUserId);
            docReportCollectImg.setRegistrationFormSoid(Long.valueOf(registrationSoid));
            docReportCollectImgService.add(docReportCollectImg);
        }
        return imagePath;
    }




    @Override
    public List<ImageVo> queryImageList(String postId) throws IOException {
        List<ImageVo> imageVos = new ArrayList<>();
        DocReportCollectImg examination = docReportCollectImgService.queryExamination(postId);
        if (null != examination){
            //1、连接ftp服务器
            FTPClient ftpClient = new FTPClient();
            ftpClient.connect(url, port);
            //2、登录ftp服务器
            ftpClient.login("anonymous", "");
            String imagePath = examination.getImagePath();
            // 跳转到文件目录
            ftpClient.changeWorkingDirectory(imagePath);
            //设置连接模式，不设置会获取为空
            ftpClient.enterLocalPassiveMode();
            // 获取目录下文件集合
            FTPFile[] files = ftpClient.listFiles();
            InputStream in = null;
            ByteArrayOutputStream outputStream = null;
            String base64 = "";
            for (FTPFile file : files) {
                in = ftpClient.retrieveFileStream(file.getName());
                if (null != in){
                    byte[] data = new byte[1024];
                    outputStream = new ByteArrayOutputStream();
                    int len = 0;
                    while (-1 != (len = in.read(data))) {
                        outputStream.write(data, 0, len);
                    }
                    data = outputStream.toByteArray();
                    Base64.Encoder encoder = Base64.getEncoder();
                    //判断当前文件是图片还是视频
                    if (file.getName().contains("png") ||  file.getName().contains("jpg")){
                        base64 = "data:image/png;base64," + encoder.encodeToString(data);
                        ImageVo imageVo = new ImageVo();
                        imageVo.setType("image");
                        imageVo.setBase(base64);
                        imageVo.setImageName(file.getName());
                        imageVos.add(imageVo);
                    }else {
                        base64 = "data:video/mp4;base64," + encoder.encodeToString(data);
                        ImageVo imageVo = new ImageVo();
                        imageVo.setType("video");
                        imageVo.setBase(base64);
                        imageVo.setImageName(file.getName());
                        imageVos.add(imageVo);
                    }
                    //关闭输入流
                    in.close();
                    //ftp传输结束
                    ftpClient.completePendingCommand();
                }
            }
            return imageVos;
        }
        return null;
    }

    /**
     * 文件上传
     * @param ftp
     * @return
     * @throws IOException
     */
    private String upload(FTPClient ftp, String postId, MultipartFile file, String sequence) throws IOException {
        InputStream in = null;
        String savePath = null;
        try {
            // 设置PassiveMode传输
            ftp.enterLocalPassiveMode();
            //设置二进制传输，使用BINARY_FILE_TYPE，ASC容易造成文件损坏
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            //判断FPT目标文件夹是否存在不存在则创建
            ftp = this.fileName(ftp, postId, sequence);
            //上传文件
            in = file.getInputStream();
            boolean flag = ftp.storeFile(new String(file.getOriginalFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1), in);
            if (flag) {
                savePath = ftp.printWorkingDirectory();
                logger.info("ftp上传成功");
            } else {
                logger.error("ftp上传失败");
            }
        } finally {
            if (in != null) {
                in.close();
            }
        }
        return savePath;
    }









    private FTPClient fileName(FTPClient ftp, String postId, String sequence) throws IOException {
        //查询当前患者是否已经有文件夹
        DocReportCollectImg docReportCollectImg = docReportCollectImgService.queryExamination(postId);
        if (null != docReportCollectImg) {
            String imagePath = docReportCollectImg.getImagePath();
            ftp.changeWorkingDirectory(imagePath);
        } else {
            String ftpPath = new SimpleDateFormat("yyyyMMdd").format(new Date());
            if (!ftp.changeWorkingDirectory(ftpPath)){
                ftp.makeDirectory(ftpPath);
                ftp.changeWorkingDirectory(ftpPath);
                //创建患者ID
                ftp.makeDirectory(sequence);
                ftp.changeWorkingDirectory(sequence);
                //创建检查号
                ftp.makeDirectory(postId);
                ftp.changeWorkingDirectory(postId);
            }else {
                ftp.changeWorkingDirectory(ftpPath);
                if (!ftp.changeWorkingDirectory(sequence)) {
                    //判断患者ID
                    ftp.makeDirectory(sequence);
                    ftp.changeWorkingDirectory(sequence);
                    if (!ftp.changeWorkingDirectory(postId)) {
                        //判断检查号
                        ftp.makeDirectory(postId);
                        ftp.changeWorkingDirectory(postId);
                    } else {
                        ftp.changeWorkingDirectory(postId);
                    }
                } else {
                    ftp.changeWorkingDirectory(sequence);
                    if (!ftp.changeWorkingDirectory(postId)) {
                        ftp.makeDirectory(postId);
                        ftp.changeWorkingDirectory(postId);
                    } else {
                        ftp.changeWorkingDirectory(postId);
                    }
                }
            }
        }
        return ftp;
    }


    @Override
    public ActionResult deleteImage(String postId, String imageName) throws IOException {
        ActionResult actionResult = new ActionResult();
        String deleteName = imageName.substring(imageName.lastIndexOf("/") + 1);
        //查询当前检查号对应的文件地址
        DocReportCollectImg examination = docReportCollectImgService.queryExamination(postId);
        if (null != examination){
            //1、连接ftp服务器
            FTPClient ftpClient = new FTPClient();
            ftpClient.connect(url, port);
            //2、登录ftp服务器
            ftpClient.login("anonymous", "");
            String imagePath = examination.getImagePath();
            // 跳转到文件目录
            ftpClient.changeWorkingDirectory(imagePath);
            ftpClient.dele(deleteName);
            buildActionSuccess(actionResult);
            return actionResult;
        }
        return null;
    }


    @Override
    public ActionResult decompression(MultipartFile multipartFile, String postId, String personSoid, String customerSoid,
                                      String registrationSoid, String fileType) throws IOException {
        ActionResult actionResult = new ActionResult();
        //1、连接ftp服务器
        FTPClient ftpClient = new FTPClient();
        ftpClient.connect(url, port);
        // 设置PassiveMode传输
        ftpClient.enterLocalPassiveMode();
        String contentType = multipartFile.getContentType();

        //设置二进制传输，使用BINARY_FILE_TYPE，ASC容易造成文件损坏
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        //2、登录ftp服务器
        ftpClient.login("anonymous", "");
        //创建文件夹
        this.fileName(ftpClient,postId,personSoid);
        InputStream in = multipartFile.getInputStream();
        boolean flag = ftpClient.storeFile(new String(multipartFile.getOriginalFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1), in);
        if (flag) {
            DocReportCollectImg examination = docReportCollectImgService.queryExamination(postId);
            if (null == examination){
                DocReportCollectImg docReportCollectImg = new DocReportCollectImg();
                docReportCollectImg.setReportCollectImgSoid(soidService.getSoid());
                docReportCollectImg.setImagePath(ftpClient.printWorkingDirectory());
                docReportCollectImg.setCreateDate(new Date());
                docReportCollectImg.setExamCheckSoid(Long.valueOf(postId));
                docReportCollectImg.setApntPersonSoid(Long.valueOf(personSoid));
                docReportCollectImg.setCustomerSoid(Long.valueOf(customerSoid));
                docReportCollectImg.setRegistrationFormSoid(Long.valueOf(registrationSoid));
                docReportCollectImgService.add(docReportCollectImg);
            }
            in.close();
            logger.info("ftp上传成功");
            buildActionSuccess(actionResult);
            return actionResult;
        }
        in.close();
        buildActionWarn(actionResult, "error");
        return actionResult;
    }


    @Override
    public ActionResult decompressionList(MultipartFile[] file, String postId, String personSoid, String customerSoid, String registrationSoid, String fileType) {
        ActionResult actionResult = new ActionResult();
        try {
            //1、连接ftp服务器
            FTPClient ftpClient = new FTPClient();
            ftpClient.connect(url, port);
            // 设置PassiveMode传输
            ftpClient.enterLocalPassiveMode();
            //设置二进制传输，使用BINARY_FILE_TYPE，ASC容易造成文件损坏
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            //2、登录ftp服务器
            ftpClient.login("anonymous", "");
            //创建文件夹
            this.fileName(ftpClient,postId,personSoid);
            InputStream in = null;
            for (MultipartFile multipartFile : file) {
                in = multipartFile.getInputStream();
                ftpClient.storeFile(new String(multipartFile.getOriginalFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1), in);
            }
            if (null != in){
                in.close();
            }
            //生成数据库记录
            DocReportCollectImg examination = docReportCollectImgService.queryExamination(postId);
            if (null == examination){
                DocReportCollectImg docReportCollectImg = new DocReportCollectImg();
                docReportCollectImg.setImagePath(ftpClient.printWorkingDirectory());
                docReportCollectImg.setCreateDate(new Date());
                docReportCollectImg.setExamCheckSoid(Long.valueOf(postId));
                docReportCollectImg.setApntPersonSoid(Long.valueOf(personSoid));
                docReportCollectImg.setCustomerSoid(Long.valueOf(customerSoid));
                docReportCollectImg.setReportCollectImgSoid(soidService.getSoid());
                docReportCollectImg.setRegistrationFormSoid(Long.valueOf(registrationSoid));
                docReportCollectImgService.add(docReportCollectImg);
            }
            logger.info("ftp上传成功");
            buildActionSuccess(actionResult);
        } catch (IOException e) {
            log.error("ftp上传失败", e);
            buildActionWarn(actionResult, "error");
        }
        return actionResult;
    }


    @Override
    public ActionResult maintainData(String postId, String personSoid, String customerSoid, String registrationSoid, String imagePath){
        //生成数据库记录
        DocReportCollectImg examination = docReportCollectImgService.queryExamination(postId);
        if (null == examination){
            DocReportCollectImg docReportCollectImg = new DocReportCollectImg();
            docReportCollectImg.setImagePath(imagePath);
            docReportCollectImg.setCreateDate(new Date());
            docReportCollectImg.setExamCheckSoid(Long.valueOf(postId));
            docReportCollectImg.setApntPersonSoid(Long.valueOf(personSoid));
            docReportCollectImg.setCustomerSoid(Long.valueOf(customerSoid));
            docReportCollectImg.setReportCollectImgSoid(soidService.getSoid());
            docReportCollectImg.setRegistrationFormSoid(Long.valueOf(registrationSoid));
            docReportCollectImgService.add(docReportCollectImg);
        }
        return null;
    }
}


